﻿// This code is released under the BSD license.
namespace PugLib
{
    using System;

    public class DelegateToCatchClause<T> : CatchClause<T> where T : Exception
    {
        private readonly Func<T, CatchResult> catchFunction;

        public DelegateToCatchClause(Func<T, CatchResult> catchFunction)
        {
            this.catchFunction = catchFunction;
        }

        public override CatchResult HandleT(T ex)
        {
            return catchFunction(ex);
        }
    }

    public abstract class CatchClause
    {
        public abstract bool CanHandle(Exception ex);
        public abstract CatchResult Handle(Exception ex);

        public static CatchClause From<T>(Func<T, CatchResult> catchFunction)
            where T : Exception
        {
            return new DelegateToCatchClause<T>(catchFunction);
        }
    }

    public abstract class CatchClause<T> : CatchClause where T : Exception
    {
        public override bool CanHandle(Exception ex)
        {
            return typeof(T).IsAssignableFrom(ex.GetType());
        }

        public abstract CatchResult HandleT(T ex);

        public override sealed CatchResult Handle(Exception ex)
        {
            return HandleT((T)ex);
        }
    }
}